import BoxUtil from "@/assets/js/utils/BoxUtil";
import Measure from '@/components/map/measure';
import SmQuery from '@/assets/js/utils/SmQuery';
import Binder from '@/utils/binder';

export default class MapService {

  /**
   *  构造函数
   * @param mapBox HgcMapBoxUtil
   */
  constructor(mapBox) {
    this.hgcMapBoxUtil = mapBox;                                                  //地图操作基础类
    this.isMapInitComplete = false;                                               //地图style初始化是否完成
    this.baseMapLayers = [];                                                      //当前显示的底图数组
    this.topCanvasLayers = [];                                                    //顶部不动的图层（标绘图层）
    this.getMap().on('style.load', this._mapStyleLoadComplete.bind(this));         //地图初始化
    this.mapDataEvent = {};                                                       //地图数据加载事件
    this.binder = new Binder();
    //创建draw数据源，并加入三个draw-point,draw-line,draw-polygon三个图层,data里添加点
    this.data = {
    };


  }

  /**
   * 绑定事件
   * @param event
   * @param fn
   */
  on(event, fn) {
    if (typeof fn !== 'function') {
      console.error('第二个参数不是方法');
      return;
    }
    if (this.mapDataEvent[event] && Array.isArray(this.mapDataEvent[event])) {
      this.mapDataEvent[event].push(fn);
    } else {
      this.mapDataEvent[event] = [fn];
    }
  }

  /**
   * 解绑事件
   * @param event
   * @param fn
   */
  off(event, fn) {
    if (typeof fn !== 'function') {
      console.error('第二个参数不是方法');
      return;
    }
    if (this.mapDataEvent[event] && Array.isArray(this.mapDataEvent[event])) {
      this.mapDataEvent[event].splice(this.mapDataEvent[event].indexOf(fn), 1);
    } else {
      this.mapDataEvent[event] = [];
    }
  }

  /**
   * 地图Style加载完成事件
   * @private
   */
  _mapStyleLoadComplete() {
    this.isMapInitComplete = true;
    this._triggerMouseEvent('map.init', this.getMap());
    this.loadPlotLayers();

  }

  /**
   * 鼠标事件触发器
   * @param evt
   * @private
   */
  _triggerMouseEvent(evt, e, id) {
    let ev = this.mapDataEvent[evt];
    let size = ev ? ev.length : 0;
    for (let i = 0; i < size; i++) {
      this.mapDataEvent[evt][i].call(this, e, id);
    }
  }

  /**
   * 获取地图
   * @returns {*}
   */
  getMap() {
    return this.hgcMapBoxUtil.getMap();
  }

  /**
   * 获取测量工具
   * @returns {Measure}
   */
  getMeasureTool() {
    return this._m;
  }

  /**
   * 地图操作类
   * @returns {*}
   */
  getHgcMapBoxUtil() {
    return this.hgcMapBoxUtil;
  }

  /**
   * 解析图层url
   * @param url
   * @private
   */
  _parseLayerUrl(url) {
    if (url) {
      this._parseLayerUrlParam(url);
      const urlArray = url.split('?');
      const realUrl = url.replace(urlArray[urlArray.length - 1], '');
      return realUrl.substring(0, realUrl.length - 1);
    }
    return url
  }

  /**
   * 解析图层查询数据
   * @param url
   * @returns {*}
   * @private
   */
  _parseLayerQueryUrl(url) {
    const real = this._parseLayerUrl(url);
    if (real.indexOf('/tileFeature') === -1) {
      return real;
    } else {
      return real.substring(0, real.indexOf('/tileFeature'));
    }
  }

  /**
   * 解析图层url参数
   * @param url
   * @private
   */
  _parseLayerUrlParam(url) {
    if (url) {
      const urlArray = url.split('?');
      try {
        var obj = JSON.parse(
          '{"' +
          decodeURIComponent(urlArray[urlArray.length - 1])
            .replace(/"/g, '\\"')
            .replace(/&/g, '","')
            .replace(/=/g, '":"') +
          '"}'
        )
      } catch (e) {
        console.log(e, "图层URL参数配置不正确，不能正常解析的JSON");
        return url;
      }
      return obj;

    }

  }

  /**
   *  添加图层
   * @param type
   * @param id    layerId的真实身份是sourceId
   * @param url
   * @param minZoom
   * @param maxZoom
   * @param beforeID
   * @returns {*}
   */
  addLayer(layer, beforeID) {
    const realUrl = this._parseLayerUrl(layer.url);
    const param = this._parseLayerUrlParam(layer.url);//layerType,searchLayer
    let promise;
    switch (param.layerType.trim()) {
      case "layer_sm_vec":   //超图发布的矢量瓦片服务
        promise = this.hgcMapBoxUtil.addVectorTileLayer(layer.param ? layer.param.id : undefined, realUrl, beforeID);
        break;
      case "layer_sm_map":   //栅格瓦片服务
        promise = this.hgcMapBoxUtil.addGridTileLayer(layer.param ? layer.param.id : undefined, realUrl, layer.minZoom, layer.maxZoom, beforeID);
        break;
      case "layer_sm_25d" :  //2.5D服务
        promise = this.hgcMapBoxUtil.addFillExtrusionLayer(layer.param ? layer.param.id : undefined, realUrl, layer.minZoom, layer.maxZoom, beforeID); //TODO  undefined 是sourcelayer
        break;
      case 'layer_tdt_map':  //天地图栅格瓦片服务
        promise = this.hgcMapBoxUtil.addTdtGridTileLayer(layer.param ? layer.param.id : undefined, realUrl, layer.minZoom, layer.maxZoom, beforeID);
        break;
      case 'layer_sm_es': //EChart服务
        promise = this.hgcMapBoxUtil.addEchartsLayer(layer.url);
        break;
      default:
        break;
    }
    return promise;
  }


  /**
   * 获取专题最下面的图层
   * @returns {undefined}
   */
  getSubjectLayersBottomLayerId() {
    var layers = this.getMap().getStyle().layers;
    if (layers && Array.isArray(layers) && layers.length > 0) {
      return layers.length > 0 ? layers[0].id : undefined;
    }
    return undefined;
  }


  /**
   * 设置图层开关
   *
   * 先对图层添加和删除，再对高亮图层的添加和删除
   * 再绑定图层的属性查询事件
   */
  setLayerVisible(isVisible, layer) {
  
  }

  /**
   * 注册鼠标事件
   * @param id
   * @private
   */
  _addMouseEventListener(id) {
    this.getMap().on('mouseenter', id, this.binder.bind(this._mouseEnterEvent, this, [id]));
    this.getMap().on('mouseleave', id, this.binder.bind(this._mouseLeaveEvent, this, [id]));
    this.getMap().on('click', id, this.binder.bind(this._mouseClickEvent, this, [id]));
  }

  /**
   * 取消鼠标事件
   * @param id
   * @private
   */
  _removeEventListener(id) {
    this.getMap().off('mouseenter', id, this.binder.getBindFunction(this._mouseEnterEvent));
    this.getMap().off('mouseleave', id, this.binder.getBindFunction(this._mouseLeaveEvent));
    this.getMap().off('click', id, this.binder.getBindFunction(this._mouseClickEvent));
  }

  /**
   * 鼠标停留在要素上方
   * @param e
   * @private
   */
  _mouseEnterEvent(id, e) {
    this.getMap().getCanvas().style.cursor = 'Pointer';
    const feature = this.getMap().queryRenderedFeatures(e.point, {layers: id});
    e.feature = feature;
    this._triggerMouseEvent('map.enter', e, id);
  }

  /**
   * 鼠标离开要素上方
   * @param e
   * @private
   */
  _mouseLeaveEvent(e) {
    this.getMap().getCanvas().style.cursor = '';
  }

  /**
   * 鼠标点击事件
   * @param e
   * @private
   */
  _mouseClickEvent(id, e) {

  }


  /**
   * 设置图层透明度
   * @param value
   * @param sourceId 数据源ID
   */
  setOpacityValue(value, layer) {
    if (layer.param && layer.param.id) {
      this.hgcMapBoxUtil.setLayerOpacity(layer.param.id, value);

    }

  }

  /**
   * 移除瓦片
   * @param soureId 数据源ID
   */
  removeLayer(sourceId) {
    this.hgcMapBoxUtil.removeTileLayer(sourceId);
  }

  /**
   * 切换底图
   * @param layerGroup
   */
  addBaseLayer(layerGroup) {
    if (!Array.isArray(layerGroup)) {
      throw ('layerGroup 不是个数组，检查数据！');
    }
    //移除
    this.baseMapLayers.forEach(layer => {
      this.removeLayer(layer.source);
    });
    this.baseMapLayers = [];
    //这里剩下专题图层
    var bottom = this.getSubjectLayersBottomLayerId();
    if (!bottom && this.topCanvasLayers.length > 0) {
      bottom = this.topCanvasLayers[0]; //TODO 有可能是最后一个
    }
    //排序再添加
    layerGroup.sort((p, n) => parseInt(n.index) - parseInt(p.index));
    layerGroup.forEach(layer => {
      this.addLayer(layer, bottom).then(res => {
        layer.param = res;
        this.baseMapLayers.push(res);
      });

    })
  }

  /**
   * 通过图层边界设置地图边界
   * @param layer
   */
  setMapBoundsByLayerBounds(layer) {

  }


  /**
   * 加载标绘图层（默认地图服务类初始化时加载）
   */
  loadPlotLayers() {
   
  }


  /**
   * 属性查询
   * @param layer
   * @param startIndex
   * @param size
   * @returns {Promise<never> | Promise<any>}
   */
  queryLayerAttribute(layer, startIndex, size) {
  
  }

  /**
   * 定位Geometry
   * @param geometry
   */
  flyTo(geometry) {
    let center;
    switch (geometry.type) {
      case 'Point':
        center = geometry.coordinates;
        break;
      case 'LineString':
        center = BoxUtil.getCenterOfLine(geometry.coordinates);
        break;
      case 'Polygon':
        center = BoxUtil.getRegionCenter(geometry.coordinates);
        break;
      case 'MultiPolygon':
        center = BoxUtil.getRegionCenter(geometry.coordinates[0][0]);
        break;
    }
    this.getMap().flyTo({center: center, zoom: 13})

  }

  /**
   * 设置高亮
   * @param layerId
   * @param smId
   */
  setHightLihgtFilter(layerId, smId) {
    this.hgcMapBoxUtil.setHighLightFilter(layerId, smId)
  }


  /**
   * 清除高亮
   * @param layerId
   */
  clearHightLightFilter(layerId) {
    this.hgcMapBoxUtil.clearHighLightFilter(layerId);
  }


  /**
   * 给Map加载符号库
   * @param symbols
   */
  addloadSymbols(symbols) {
    if (!Array.isArray(symbols)) {
      return;
    }
    symbols.forEach(symbol => {
      this.hgcMapBoxUtil.addImage(symbol.symbolName, symbol.symbolPath);
    });
  }


}













